
#include <linux/version.h>
#include <linux/kallsyms.h>
#include "ksymbol.h"

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
#include <linux/kprobes.h>
static struct kprobe kp = {
	.symbol_name = "kallsyms_lookup_name"
};

typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
static kallsyms_lookup_name_t g_syms_lookup_name;
static kallsyms_lookup_name_t get_symbol_kallsyms_lookup_name(void)
{
	unsigned long syms_lookup_name;

	register_kprobe(&kp);
	syms_lookup_name = (unsigned long)kp.addr;
	unregister_kprobe(&kp);
	return (kallsyms_lookup_name_t)syms_lookup_name;
}
#endif

unsigned long get_func_syms_by_name(const char *name)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
	if (!g_syms_lookup_name) {
		g_syms_lookup_name = get_symbol_kallsyms_lookup_name();
		if (!g_syms_lookup_name) {
			pr_err("con't get symbol of kallsyms_lookup_name\n");
			return 0;
		}
	}
	return g_syms_lookup_name(name);
#else
	return kallsyms_lookup_name(name);
#endif
}

